﻿using System.Collections.Generic;
using Headsight.BPMN2WF.BPMN.BlockModel;
using Headsight.BPMN2WF.BPMN.Model;
using Headsight.BPMN2WF.BPMN.Schemas;
using Headsight.BPMN2WF.Testing.TestObjCtors;
using Headsight.BPMN2WF.Transformation.BPMN2TransformerMappings.Config;
using Headsight.BPMN2WF.Transformation.Transformers;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Rhino.Mocks;

namespace Headsight.BPMN2WF.Transformation.BPMN2TransformerMappings
{
    [TestClass]
    public class BPMN2WFTransformationsXmlV2Test
    {
        private readonly string _mappingFile = Properties.Settings.Default.TestingRootDir + @"\Headsight.BPMN2WFTest\Transformation\MappingConfigFiles\MappingAdvanced.xml";

        private BPMN2WFTransformationConfig _sut;
        private BPMNFlowNode _bpmnFlowNode;

        [TestInitialize]
        public void SetUp()
        {
            _sut = new BPMN2WFTransformationConfig(_mappingFile);
            _bpmnFlowNode = new BPMNFlowNodeCtor().WithTFlowElement(new tUserTask()).WithId("**id1**").Create();
        }

        [TestMethod]
        public void TestBPMN2WFTransformationDummyActivity()
        {
            var bpmnFlowNodeBlock = new BPMNFlowNodesBlockEmpty("**id1**", _bpmnFlowNode);
            Assert.IsInstanceOfType(_sut.Get(bpmnFlowNodeBlock), typeof (BPMN2WFTransformationDummyActivity));
        }

        [TestMethod]
        public void TestBPMN2WFTransformationExclusiveGateway()
        {
            var tDefCtor = new tDefinitionsCtor();
            var tProCtor = new tProcessCtor().WithId("Name").WithName("Name");
            var tCreator = new tGatewayExclusiveCtor(tProCtor, "_id_tExclusiveGateway").WithName("_name_tExclusiveGateway")
                .IfExpression("True = False")
                .ThenTask(typeof(tUserTask), "_id_tUserTask1", "_name_tUserTask1")
                .IfExpression("True = False")
                .ThenTask(typeof(tUserTask), "_id_tUserTask2", "_name_tUserTask2")
                .Default()
                .ThenTask(typeof(tUserTask), "_defaultId", "__defaultName");

            var tDefinitions = tDefCtor.With(tProCtor.With(tCreator)).Create();
            var bpmnDefinitions = new BPMNFlowNodesBlockFactory().CreateBPMNFlowNodesBlock(tDefinitions);
            Assert.IsInstanceOfType(_sut.Get(bpmnDefinitions), typeof(BPMN2WFTransformationExclusiveGateway));
        }

        [TestMethod]
        public void TestBPMN2WFTransformationInclusiveGateway()
        {
            var tDefCtor = new tDefinitionsCtor();
            var tProCtor = new tProcessCtor().WithId("Name").WithName("Name");
            var tCreator = new tGatewayInclusiveCtor(tProCtor, "_id_tInclusiveGateway").WithName("_name_tInclusiveGateway")
                .IfExpression("True = False")
                .ThenTask(typeof(tUserTask), "_id_tUserTask1", "_name_tUserTask1")
                .IfExpression("True = False")
                .ThenTask(typeof(tUserTask), "_id_tUserTask2", "_name_tUserTask2")
                .Default()
                .ThenTask(typeof(tUserTask), "_defaultId", "__defaultName");

            var tDefinitions = tDefCtor.With(tProCtor.With(tCreator)).Create();
            var bpmnDefinitions = new BPMNFlowNodesBlockFactory().CreateBPMNFlowNodesBlock(tDefinitions);
            Assert.IsInstanceOfType(_sut.Get(bpmnDefinitions), typeof(BPMN2WFTransformationInclusiveGateway));
        }

        [TestMethod]
        public void TestBPMN2WFTransformationGateway()
        {
            var tDefCtor = new tDefinitionsCtor();
            var tProCtor = new tProcessCtor().WithId("Name").WithName("Name");
            var tCreator = new tGatewayCtor(tProCtor, "_id_tInclusiveGateway").WithName("_name_tInclusiveGateway")
                .IfExpression("True = False")
                .ThenTask(typeof(tUserTask), "_id_tUserTask1", "_name_tUserTask1")
                .IfExpression("True = False")
                .ThenTask(typeof(tUserTask), "_id_tUserTask2", "_name_tUserTask2");

            var tDefinitions = tDefCtor.With(tProCtor.With(tCreator)).Create();
            var bpmnDefinitions = new BPMNFlowNodesBlockFactory().CreateBPMNFlowNodesBlock(tDefinitions);
            Assert.IsInstanceOfType(_sut.Get(bpmnDefinitions), typeof(BPMN2WFTransformationExclusiveGateway));
        }

        [TestMethod]
        public void TestBPMN2WFTransformationGatewayNoBlock()
        {
            var tProCtor = new tProcessCtor().WithId("Name").WithName("Name");
            var tCreator = new tGatewayCtor(tProCtor, "_id_tGateway").WithName("_name_tGateway")
                .IfExpression("True = False")
                .ThenTask(typeof(tUserTask), "_id_tUserTask1", "_name_tUserTask1")
                .IfExpression("True = False")
                .ThenTask(typeof(tUserTask), "_id_tUserTask2", "_name_tUserTask2").Create();
            var processCreator = new tProcessCtor().With(tCreator).WithId("tGateway").WithName("tGateway").Create();

            var bpmnMFacArgs = MockRepository.GenerateStub<BPMNArgumentFactory>();
            var bpmnMFacParams = new BPMNModelFactoryParamsCtor().With(bpmnMFacArgs).Create();

            var actual = new BPMNFlowNodeFactoryImpl().CreateBPMNFlowNodes(processCreator, new List<BPMNSequenceFlow>(), bpmnMFacParams);
            Assert.IsInstanceOfType(_sut.Get(actual[0]), typeof(BPMN2WFTransformationConvergingActivity));
        }

        [TestMethod]
        public void TestBPMN2WFTransformationFlowchart()
        {
            var tDefCtor = new tDefinitionsCtor();
            var tProCtor = new tProcessCtor().With(new tFlowNodeCtor().WithId("_1")).WithId("Name").WithName("Name");
            var tDefinitions = tDefCtor.With(tProCtor).Create();
            var bpmnDefinitions = new BPMNFlowNodesBlockFactory().CreateBPMNFlowNodesBlock(tDefinitions);
            Assert.IsInstanceOfType(_sut.Get(bpmnDefinitions), typeof(BPMN2WFTransformationFlowchart));
        }

        [TestMethod]
        public void TestBPMN2WFTransformationCustomWFUserTask()
        {
            var tProCtor = new tProcessCtor().With(new tFlowNodeCtor().WithId("_1")).WithId("Name").WithName("Name").Create();

            var bpmnMFacArgs = MockRepository.GenerateStub<BPMNArgumentFactory>();
            var bpmnMFacParams = new BPMNModelFactoryParamsCtor().With(bpmnMFacArgs).Create();

            var actual = new BPMNFlowNodeFactoryImpl().CreateBPMNFlowNodes(tProCtor, new List<BPMNSequenceFlow>(), bpmnMFacParams);
            Assert.IsInstanceOfType(_sut.Get(actual[0]), typeof(BPMN2WFTransformationCustomWFUserTask));
        }

        [TestMethod]
        public void TestDefault()
        {
            var tProCtor = new tProcessCtor().With(new tChoreographyTask()).WithId("_1").Create();

            var bpmnMFacArgs = MockRepository.GenerateStub<BPMNArgumentFactory>();
            var bpmnMFacParams = new BPMNModelFactoryParamsCtor().With(bpmnMFacArgs).Create();

            var actual = new BPMNFlowNodeFactoryImpl().CreateBPMNFlowNodes(tProCtor, new List<BPMNSequenceFlow>(), bpmnMFacParams);
            Assert.IsInstanceOfType(_sut.Get(actual[0]), typeof(BPMN2WFTransformationWriteLine));
        }

    }
}
